package controller

import (
	"errors"
	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
	"library/Vo"
	"library/common"
	"library/config"
	"library/model"
	"log"
	"strconv"
)

func AddNewBook(ctx *gin.Context) {
	//上架新书
	bookName := ctx.PostForm("name")
	author := ctx.PostForm("author")
	summary := ctx.PostForm("summary")
	year := ctx.PostForm("year")
	tags := ctx.PostFormArray("tags")
	identityId := ctx.PostForm("identity_id")

	db := config.GetDB()
	var book model.Book
	err := db.Where("identity_id = ?", identityId).First(&book).Error
	if !errors.Is(err, gorm.ErrRecordNotFound) {
		//索书号应该是唯一的，已经存在书籍，不允许上架
		Vo.ResponseFiled(ctx, common.StatusAddFailed, "书籍已经存在")
		return
	}

	tx := db.Begin() // 开启事务

	// 新建书籍描述信息
	var bookDesc model.BookDesc
	err = tx.Where("book_name = ?", bookName).First(&bookDesc).Error
	if errors.Is(err, gorm.ErrRecordNotFound) {
		y, err := strconv.Atoi(year)
		if err != nil {
			Vo.ResponseFiled(ctx, common.StatusUnknown, "字符串转数字err")
			return
		}
		bookDesc = model.BookDesc{
			BookName: bookName,
			Author: author,
			Summary: summary,
			Year: y,
		}
		if rows := tx.Create(&bookDesc).RowsAffected; rows == 0 {
			Vo.ResponseFiled(ctx, common.StatusAddFailed, "添加书籍失败")
			tx.Rollback() // 回滚操作
			return
		}
		log.Println("添加书籍描述信息成功：",bookDesc.ID, bookDesc.BookName, bookDesc.Author)
	}

	//新建Book数据
	book = model.Book{
		IdentityId: identityId,
		DescriptionId: bookDesc.ID,
		BorrowStatus: false,
	}
	if rows := tx.Create(&book).RowsAffected; rows == 0 {
		Vo.ResponseFiled(ctx, common.StatusAddFailed, "添加书籍失败")
		tx.Rollback()
		return
	}
	log.Println("添加书籍信息：", book.ID, book.IdentityId, book.DescriptionId)

	//建立图书和标签的对应关系
	for _, _tag := range tags {
		var tagDesc model.TagDesc
		err := tx.Where("tag_name = ?", _tag).First(&tagDesc).Error
		if errors.Is(err, gorm.ErrRecordNotFound) {
			// 找不到对应的标签信息，则新建一个
			tagDesc.TagName = _tag
			if rows := tx.Create(&tagDesc).RowsAffected; rows == 0 {
				Vo.ResponseFiled(ctx, common.StatusAddFailed, "添加标签信息失败")
				tx.Rollback()
				return
			}
		}
		tag := model.Tag{
			TagDescId: tagDesc.ID,
			BookId: book.ID,
		}
		if rows := tx.Create(&tag).RowsAffected; rows == 0 {
			Vo.ResponseFiled(ctx, common.StatusAddFailed, "添加标签信息失败")
			tx.Rollback()
			return
		}
		log.Println("添加标签和书籍的对应关系成功：", tag.BookId, tag.TagDescId)
	}

	//到此，上架图书成功
	responseBody := gin.H{"bookDesc":bookDesc, "book":book}
	Vo.ResponseSuccess(ctx,common.StatusAddSuccess, responseBody,"添加图书表述信息成功")
	tx.Commit()	//添加书籍成功，提交事务
}

func DeleteBook(ctx *gin.Context) {
	//下架书籍 TODO
	identityId := ctx.PostForm("identity_id")

	db := config.GetDB()
	tx := db.Begin() // 手动开启事务
	var book model.Book
	err := tx.Where("identity_id = ?", identityId).First(&book).Error
	if errors.Is(err, gorm.ErrRecordNotFound) {
		Vo.ResponseFiled(ctx, common.StatusBookNotFound, "书籍不存在")
		return
	}
	if rows := tx.Delete(&book).RowsAffected; rows == 0 {
		Vo.ResponseFiled(ctx, common.StatusDeleteFailed, "书籍下架失败")
		tx.Rollback()
		return
	}else {
		log.Println("删除book表数据条数：", rows)
	}
	if rows := tx.Where("book_id = ?", book.ID).Delete(&model.Tag{}).RowsAffected; rows == 0 {
		Vo.ResponseFiled(ctx, common.StatusDeleteFailed, "书籍下架失败")
		tx.Rollback()
		return
	}else {
		log.Println("删除tag表数据条数：", rows)
	}

	// 如果book对应的bookDesc记录已经没有书在引用了，那么应该删除该bookDesc TODO
	// 同理，如果book对应的标签tag已经没有引用了，应该删除 TODO

	responseBody := gin.H{"book":book}
	Vo.ResponseSuccess(ctx,common.StatusDeleteSuccess, responseBody,"下架书籍成功")
	tx.Commit()
}

func UpdateBook(ctx *gin.Context) {
	//更新图书 TODO

}

func recordHaveExist(err error, msg string, ctx *gin.Context) {
	//当数据已存在时，封装返回响应 TODO

}